      SUBROUTINE GETOKE ( LINE, LEN, IPTR, TOKEN, TYPE, ERROR )
C*
C*                  *******************************
C*                  *******************************
C*                  **                           **
C*                  **          GETOKE           **
C*                  **                           **
C*                  *******************************
C*                  *******************************
C*
C*     SUBPROGRAM :
C*          GET TOKEN
C*
C*     AUTHOR :
C*          ART RAGOSTA
C*          MS 207-5
C*          AMES RESEARCH CENTER
C*          MOFFETT FIELD, CA  94035
C*          (415) 694-5578
C*
C*     PURPOSE :
C*          EXTRACT THE NEXT TOKEN FROM A CHARACTER STRING USING
C*          THE FOLLOWING CONVENTIONS :
C*               1. MORE THAN ONE CONSECUTIVE SPACE IS TREATED AS A
C*                   SINGLE SPACE.
C*               2. TWO CONSECUTIVE DELIMITERS RETURN A NULL TOKEN.
C*               3. WORDS MUST BEGIN WITH A CHARACTER.
C*               4. NUMBERS MUST BEGIN WITH A DIGIT.
C*               5. ALL OTHER CHARACTERS ARE RETURNED VERBATIM.
C*               6. VALID DELIMITERS ARE  , ; : AND <SPACE>.
C*
C*     INPUT ARGUMENTS :
C*          LINE - THE LINE TO BE PARSED.
C*          LEN  - THE LAST CHARACTER TO SCAN IN LINE.
C*          IPTR - THE LOCATION FROM WHICH PARSING IS TO BEGIN.
C*
C*     OUTPUT ARGUMENTS :
C*          IPTR  - THE LAST CHARACTER IN LINE THAT WAS SCANNED.
C*          TOKEN - THE CHARACTER *20 RESULT.
C*          ERROR - AN ERROR OCCURRED IN PARSING THE LINE.
C*
C*     INTERNAL WORK AREAS :
C*          NONE
C*
C*     COMMON BLOCKS :
C*          NONE
C*
C*     FILE REFERENCES :
C*          NONE
C*
C*     DATA BASE ACCESS :
C*          NONE
C*
C*     SUBPROGRAM REFERENCES :
C*          NONE
C*
C*     ERROR PROCESSING :
C*          NONE
C*
C*     TRANSPORTABILITY LIMITATIONS :
C*          NONE
C*
C*     ASSUMPTIONS AND RESTRICTIONS :
C*          NONE
C*
C*     LANGUAGE AND COMPILER :
C*          ANSI FORTRAN 77
C*
C*     VERSION AND DATE :
C*          VERSION I.0      3-OCT-84
C*
C*     CHANGE HISTORY :
C*           3-OCT-84    INITIAL VERSION
C*
C***********************************************************************
C*
      CHARACTER *(*) LINE
      CHARACTER *20 TOKEN
      CHARACTER *1 EOL,CH,TYPE
      INTEGER TSIZE
      LOGICAL ERROR
C
C --- END OF LINE INDICATOR
C
      EOL = CHAR(13)
C
C --- SKIP LEADING BLANKS
C
      IF ( IPTR .LT. 1 ) IPTR = 1
      CH = LINE(IPTR:IPTR)
C
C --- WHILE CH = ' ' DO GETCH
C
10    IF ( CH .NE. ' ' ) GO TO 20
      IPTR = IPTR + 1
      IF ( IPTR .GT. LEN ) THEN
         CH = EOL
         GO TO 20
      ENDIF
      CH = LINE(IPTR:IPTR)
      GO TO 10
C
C --- END WHILE CH = ' '
C
C --- IF CHARACTER IS DELIMITER, RETURN A NULL VALUE
C
20    TOKEN = ' '
      IF ((CH .EQ. ',') .OR. (CH .EQ. ';') .OR. (CH .EQ. ':')
     $  .OR. (CH .EQ. EOL)) THEN
C
C ----- FIRST CHARACTER WAS A DELIMITER... RETURN A NULL VALUE
C
         TYPE  = 'N'
         IF ( CH .NE. EOL ) THEN
            IPTR = IPTR + 1
         ELSE
            TYPE = 'E'
         ENDIF
      ELSE
C
C --- FIRST CHARACTER WAS NOT A DELIMITER
C
         IF ((CH .GE. 'A') .AND. (CH .LE. 'Z')) THEN
C
C ----- ALPHABETIC TOKEN
C
            TYPE = 'A'
C
C -------     WHILE (CH IN ALPHA+DIGITS) PACK CHARACTERS INTO TOKEN
C
            TSIZE = 1
30          IF (TSIZE .LE. 20) TOKEN(TSIZE:TSIZE) = CH
            TSIZE = TSIZE + 1
            IPTR = IPTR + 1
            IF ( IPTR .GT. LEN ) THEN
               CH = EOL
            ELSE
               CH = LINE(IPTR:IPTR)
            ENDIF
            IF (((CH .GE. 'A') .AND. (CH .LE. 'Z')) .OR.
     $       ((CH .GE. '0') .AND. (CH .LE. '9'))) GO TO 30
C
C ----- END WHILE (CH IN ALPHA+DIGITS)
C
         ELSE IF (((CH .GE. '0') .AND. (CH .LE. '9')) .OR.
     $            (CH .EQ. '+') .OR. (CH .EQ. '-')) THEN
C
C ----- NUMERICAL TYPE... DEFAULT TO INTEGER
C
            TYPE = 'I'
            TSIZE = 1
            IF ((CH .EQ. '-') .OR. (CH .EQ. '+')) THEN
               TOKEN(TSIZE:TSIZE) = CH
               IPTR = IPTR + 1
               CH = LINE(IPTR:IPTR)
               IF ((CH .NE. '.') .AND.
     $            ((CH .LT. '0') .OR. (CH .GT. '9'))) THEN
                  IPTR = IPTR - 1
                  TYPE = 'S'
                  RETURN
               ENDIF
               TSIZE = TSIZE + 1
            ENDIF
C
C ------ WHILE (CH IN DIGITS+'E'+'.') PACK CHARACTERS INTO TOKEN
C
40          IF (TSIZE .LE. 20) TOKEN(TSIZE:TSIZE) = CH
            TSIZE = TSIZE + 1
            IPTR = IPTR + 1
            IF ( IPTR .GT. LEN ) THEN
               CH = EOL
            ELSE
               CH = LINE(IPTR:IPTR)
            ENDIF
            IF ((CH .GE. '0') .AND. (CH .LE. '9')) GO TO 40
C
C -------- EITHER '.' OR 'E' INDICATE A REAL NUMBER
C
            IF (CH .EQ. '.') THEN
               TYPE = 'R'
               GO TO 40
            ENDIF
            IF (CH .EQ. 'E') THEN
C
C ----------- EXPONENT FOUND
C
               TYPE = 'R'
50             IF (TSIZE .LE. 20) TOKEN(TSIZE:TSIZE) = CH
               TSIZE = TSIZE + 1
               IPTR = IPTR + 1
               IF ( IPTR .GT. LEN ) THEN
                  CH = EOL
               ELSE
                  CH = LINE(IPTR:IPTR)
               ENDIF
C
C ------------ '+' AND '-' PERMITTED AS FIRST CHARACTER IN EXPONENT
C
               IF ((CH .EQ. '+') .OR. (CH .EQ. '-')) THEN
                  GO TO 50
               ELSE
                  GO TO 40
               ENDIF
            ENDIF
C
C ------ END WHILE (CH IN DIGITS+'E'+'.')
C
C ------ OTHERWISE, RETURN THE SPECIAL CHARACTER ONLY
C
         ELSE
            TYPE = 'S'
            TOKEN(1:1) = CH
         ENDIF
      ENDIF
C
C --- SKIP THE DELIMITER
C
60    IF ( CH .NE. ' ' ) GO TO 70
      IPTR = IPTR + 1
      IF ( IPTR .GT. LEN ) THEN
         CH = EOL
         GO TO 70
      ENDIF
      CH = LINE(IPTR:IPTR)
      GO TO 60
70    IF ((CH .EQ. ',') .OR. (CH .EQ. ';') .OR. (CH .EQ. ':'))
     $ IPTR = IPTR + 1
      RETURN
      END
C
C---END GETOKE
C
